﻿using Interface.DAO;
using JMI_Nucleo.Classe;
using JMI_Nucleo.Enumerador;
using JMI_Nucleo.JMIProvider;
using OR;
using OR.Enumerador;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dao
{
    public class UsuarioDao : IUsuarioDao<mUsuario>
    {
        private mUsuario infoUsuario;
        private short codigo;

        public UsuarioDao()
        {
        }

        #region Comando SQL
        const string cmdInsertSQL = @"INSERT INTO cadastro.usuario(codigo, datacadastro, empresa, dataalteracao, 
                                    ativo, nome, senha, administrador, super, funcionario, transferidopda, 
                                    situacaoregistropda, gerente) 
                                    VALUES(@codigo, @datacadastro, @empresa, @dataalteracao, @ativo, @nome, @senha, 
                                    @administrador, @super, @funcionario, @transferidopda, 
                                    @situacaoregistropda, @gerente)";

        const string cmdUpdateSQL = @"UPDATE cadastro.usuario SET dataalteracao=@dataalteracao, ativo=@ativo,
                                      nome=@nome, senha=@senha, administrador=@administrador, super=@senha,
                                      funcionario=@funcionario, transferidopda=@transferidopda, 
                                      situacaoregistropda=@situacaoregistropda, gerente=@gerente ";

        const string cmdDeleteSQL = @"DELETE FROM cadastro.usuario ";

        const string cmdSelectSQL = @"SELECT codigo, datacadastro, empresa, dataalteracao, ativo, nome, senha, 
                                      administrador, super, funcionario, transferidopda, situacaoregistropda, 
                                      gerente FROM cadastro.usuario ";

        const string cmdExisteAdministradorCadastrado = @"SELECT * FROM cadastro.usuario 
                                                          WHERE administrador = True AND empresa =@PAR_EMPRESA";

        const string cmdRetornaLista = @"SELECT U.codigo, U.nome, U.datacadastro, U.administrador, U.ativo,
                                    P.nome AS nome_funcionario FROM cadastro.usuario U
                                    LEFT OUTER JOIN cadastro.funcionario F
                                    ON (U.funcionario = F.codigo AND U.empresa = F.empresa)
                                    LEFT OUTER JOIN cadastro.pessoa P
                                    ON (F.pessoa = P.indice AND F.empresa = P.empresa) ";

        #endregion

        public short Codigo
        {
            get { return codigo; }
            set { codigo = value; }
        }

        #region Metodos Publicos
        bool IUsuarioDao<mUsuario>.Inserir(mUsuario infoUsuario)
        {
            bool sucesso = false;
            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdInsertSQL;
                GeraParametro(ref _cmd, infoUsuario, 1);
                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);                
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = " bool IUsuarioDao<mUsuario>.Inserir(mUsuario infoUsuario)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }
        bool IUsuarioDao<mUsuario>.Alterar(mUsuario infoUsuario)
        {
            bool sucesso = false;
            DbParameter p = null;
            string cmdSQL = String.Empty;

            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                cmdSQL = cmdUpdateSQL;
                cmdSQL += "WHERE codigo =@PAR_CODIGO AND empresa =@PAR_EMPRESA";
                _cmd.CommandText = cmdSQL;
                
                GeraParametro(ref _cmd, infoUsuario, 2);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_CODIGO";
                p.Value = infoUsuario.Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = infoUsuario.CodigoEmpresa;
                _cmd.Parameters.Add(p);

                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);                
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "bool IUsuarioDao<mUsuario>.Alterar(mUsuario infoUsuario)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }
        bool IUsuarioDao<mUsuario>.Excluir(int Codigo, short Empresa)
        {
            bool sucesso = false;
            DbParameter p = null;
            string cmdSQL;

            try
            {
                DbCommand _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                cmdSQL = cmdDeleteSQL;
                cmdSQL += "WHERE codigo =@PAR_CODIGO AND empresa =@PAR_EMPRESA";
                _cmd.CommandText = cmdSQL;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_CODIGO";
                p.Value = infoUsuario.Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = infoUsuario.CodigoEmpresa;
                _cmd.Parameters.Add(p);

                _cmd.Prepare();

                sucesso = EngineBD.ExecuteNonQuery(_cmd);       
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "bool IUsuarioDao<mUsuario>.Excluir(int Indice, short Empresa)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            return sucesso;
        }
        bool IUsuarioDao<mUsuario>.ExisteCadastro()
        {
            bool retorno = false;

            DbDataReader rd = null;
            DbCommand _cmd = null;

            try
            {

                _cmd = EngineBD.GetConexao.CreateCommand();

                DbParameter p = _cmd.CreateParameter();
                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdSelectSQL;

                rd = EngineBD.ExecuteDataReader(_cmd);

                if (rd.Read())
                    retorno = true;
            }
            finally
            {
                rd.Close();
            }
            return retorno;
        }
        bool IUsuarioDao<mUsuario>.ExisteAdministradorCadastro(short Empresa)
        {
            bool retorno = false;

            DbDataReader rd = null;
            DbCommand _cmd = null;

            try
            {

                _cmd = EngineBD.GetConexao.CreateCommand();

                DbParameter p = _cmd.CreateParameter();
                _cmd.CommandType = CommandType.Text;
                _cmd.CommandText = cmdExisteAdministradorCadastrado;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = Empresa;
                _cmd.Parameters.Add(p);

                rd = EngineBD.ExecuteDataReader(_cmd);

                if (rd.Read())
                    retorno = true;
            }
            finally
            {
                rd.Close();
            }
            return retorno;
        }
        bool IUsuarioDao<mUsuario>.ValidaUsuario(string Nome, string Senha, short Empresa)
        {
            bool retorno = false;

            DbDataReader rd = null;
            DbCommand _cmd = null;
            string cmdSQL = String.Empty;

            try
            {
                _cmd = EngineBD.GetConexao.CreateCommand();

                DbParameter p = _cmd.CreateParameter();
                _cmd.CommandType = CommandType.Text;

                cmdSQL = cmdSelectSQL;
                cmdSQL += "WHERE nome =@PAR_NOME AND senha =@PAR_SENHA ";
                if (Empresa > 0)
                    cmdSQL += "AND empresa =@PAR_EMPRESA";
                _cmd.CommandText = cmdSQL;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_NOME";
                p.Value = Nome;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_SENHA";
                p.Value = Senha;
                _cmd.Parameters.Add(p);

                if (Empresa > 0)
                {
                    p = _cmd.CreateParameter();
                    p.ParameterName = "@PAR_EMPRESA";
                    p.Value = Empresa;
                    _cmd.Parameters.Add(p);
                }
                rd = EngineBD.ExecuteDataReader(_cmd);

                if (rd.Read())
                {
                    Codigo = Convert.ToInt16(rd["codigo"]);
                    retorno = true;
                }
            }
            finally
            {
                rd.Close();
            }
            return retorno;
        }
        mUsuario IUsuarioDao<mUsuario>.GetUsuario(int Codigo, short Empresa)
        {
            infoUsuario = new mUsuario();
            DbDataReader rd = null;
            DbCommand _cmd = null;
            DbParameter p = null;
            string cmdSQL;

            try
            {
                _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                cmdSQL = cmdSelectSQL;
                cmdSQL += "WHERE codigo =@PAR_CODIGO AND empresa =@PAR_EMPRESA";
                _cmd.CommandText = cmdSQL;

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_CODGIO";
                p.Value = Codigo;
                _cmd.Parameters.Add(p);

                p = _cmd.CreateParameter();
                p.ParameterName = "@PAR_EMPRESA";
                p.Value = Empresa;
                _cmd.Parameters.Add(p);

                rd = EngineBD.ExecuteDataReader(_cmd);

                if (rd.Read())
                    infoUsuario = GetRdUsuario(rd);

                return infoUsuario;
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "mUsuario IUsuarioDao<mUsuario>.GetUsuario(int Codigo, short Empresa)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            finally
            {
                rd.Close();
            }
            return infoUsuario;
        }

        List<mUsuario> IUsuarioDao<mUsuario>.GetLista(short Empresa, bool Administrador)
        {
            mUsuario infoUsuario;
            List<mUsuario> lst = new List<mUsuario>();
            DbDataReader rd = null;
            DbCommand _cmd = null;
            DbParameter p = null;
            string cmdSQL;

            try
            {
                _cmd = EngineBD.GetConexao.CreateCommand();

                _cmd.CommandType = CommandType.Text;
                cmdSQL = cmdRetornaLista;
                if (!Administrador)
                    cmdSQL += "WHERE U.empresa =@PAR_EMPRESA ";

                cmdSQL += "ORDER BY U.nome";
                _cmd.CommandText = cmdSQL;

                if (!Administrador)
                {
                    p = _cmd.CreateParameter();
                    p.ParameterName = "@PAR_EMPRESA";
                    p.Value = Empresa;
                    _cmd.Parameters.Add(p);
                }
                rd = EngineBD.ExecuteDataReader(_cmd);

                while (rd.Read())
                {
                    infoUsuario = new mUsuario();
                    infoUsuario.Codigo = Convert.ToInt32(rd["codigo"]);
                    infoUsuario.Nome = rd["nome"].ToString();
                    infoUsuario.DataCadastro = Convert.ToDateTime(rd["datacadastro"]);
                    infoUsuario.Administrador = Convert.ToBoolean(rd["administrador"]);
                    infoUsuario.Ativo = Convert.ToBoolean(rd["ativo"]);
                    infoUsuario.Funcionario.Pessoa.Nome = rd["nome_funcionario"].ToString();
                    lst.Add(infoUsuario);
                }
                return lst;
            }
            catch (Exception ex)
            {
                #region Grava log local
                mLog _info = new mLog();
                _info._TipoErro = TipoErro.Erro;
                _info.Mensagem = "Erro ao executar comando. " + ex.Message;
                _info.Metodo = "mUsuario IUsuarioDao<mUsuario>.GetUsuario(int Codigo, short Empresa)";
                _info.StackTrace = ex.StackTrace;
                _info.Tabela = String.Empty;
                LogLocal.Info = _info;
                LogLocal.Gravar();
                #endregion
            }
            finally
            {
                rd.Close();
            }
            return lst;
        }
        #endregion

        #region Metodos privados
        private mUsuario GetRdUsuario(DbDataReader rd)
        {
            infoUsuario = new mUsuario();

            infoUsuario.Codigo = Convert.ToInt32(rd["codigo"]);
            infoUsuario.DataCadastro = Convert.ToDateTime(rd["datacadastro"]);
            infoUsuario.CodigoEmpresa = Convert.ToInt16(rd["empresa"]);
            infoUsuario.DataAlteracao = Convert.ToDateTime(rd["dataalteracao"]);
            infoUsuario.Ativo = Convert.ToBoolean(rd["ativo"]); 
            infoUsuario.Nome = rd["nome"].ToString();
            infoUsuario.Senha = rd["senha"].ToString();
            infoUsuario.Administrador = Convert.ToBoolean(rd["administrador"]);
            infoUsuario.Super = Convert.ToBoolean(rd["super"]);
            infoUsuario.Funcionario.Codigo = Convert.ToInt16(rd["funcionario"]);
            infoUsuario.TransferidoPda = Convert.ToBoolean(rd["transferidopda"]);
            infoUsuario.SituacaoRegistroPda = (eSituacaoRegistroPDA)Convert.ToInt32(rd["situacaoregistropda"]);
            infoUsuario.Gerente = Convert.ToBoolean(rd["gerente"]);

            return infoUsuario;
        }
        private void GeraParametro(ref DbCommand _cmd, mUsuario infoUsuario, byte Acao)
        {
            _cmd.Parameters.Clear();
            JMIUtil jmiUtil = new JMIUtil();

            if (Acao == 1)
            {
                infoUsuario.Codigo = UtilBD.GetID(EngineBD.GetConexao, "cadastro.usuario", "codigo", infoUsuario.CodigoEmpresa);
                UtilBD.AdicionaParametro(ref _cmd, "@codigo", infoUsuario.Codigo);
                UtilBD.AdicionaParametro(ref _cmd, "@empresa", infoUsuario.CodigoEmpresa);
            }
            UtilBD.AdicionaParametro(ref _cmd, "@datacadastro", infoUsuario.DataCadastro);
            UtilBD.AdicionaParametro(ref _cmd, "@dataalteracao", infoUsuario.DataAlteracao);
            UtilBD.AdicionaParametro(ref _cmd, "@ativo", infoUsuario.Ativo);
            UtilBD.AdicionaParametro(ref _cmd, "@nome", infoUsuario.Nome);
            UtilBD.AdicionaParametro(ref _cmd, "@senha", infoUsuario.Senha);
            UtilBD.AdicionaParametro(ref _cmd, "@administrador", infoUsuario.Administrador);
            UtilBD.AdicionaParametro(ref _cmd, "@super", infoUsuario.Super);
            UtilBD.AdicionaParametro(ref _cmd, "@funcionario", infoUsuario.Funcionario);
            UtilBD.AdicionaParametro(ref _cmd, "@transferidopda", infoUsuario.TransferidoPda);
            UtilBD.AdicionaParametro(ref _cmd, "@situacaoregistropda", infoUsuario.SituacaoRegistroPda);
            UtilBD.AdicionaParametro(ref _cmd, "@gerente", infoUsuario.Gerente);
        }
        #endregion
    }
}
